/* 
 * File:   Directory.h
 * Author: Usama Shaikh
 *
 * Created on February 20, 2011, 12:00 PM
 */

#ifndef DIRECTORY_H
#define	DIRECTORY_H
#include "BlockGroup.h"
#include "Block.h"
#include "DirectoryEntry.h"
#include "FreeList.h"
#include <string>
#include <vector>
#include <stdio.h>
#include <iostream>

using namespace std;

class Directory {
public:

    /**
     * Creates a new directory objecct. If createNew is true, it creates a
     * 1 block Directory by getting block from freelist. Else it reads from the
     * master block the parameters to initialize Directory:BlockGroup.
     * Does not modify disk
     * @param fl pointer to freelist for Directory
     * @param createNew decides whether to create new directory or read from
     * master Block
     */
    Directory(FreeList * fl, bool createNew);



    /**
     * Default Destructor
     */
    ~Directory();

    /**
     * Reads directory entries in this directory from Disk to RAM into
     * directoryEntries STL vector
     */
    void Open();

    /**
     * Lists all the directory entries in this Directory in RAM
     * @return STL Vector pointer to all DirectoryEntries in this block
     */
    vector<DirectoryEntry> List();

    /**
     * Looks for a DirectoryEntry in RAM associated with the fileName provided.
     * Returns the FCB pointer if the file is found. Otherwise returns -1.
     * @param fileName File Name to be searched in Directory entries
     * @return File Control Block (FCB) of that Entry if found. Else -1.
     */
    int Find(char* fileName);

    /**
     * This method is called to write the current state of Directory from RAM
     * to Disk.
     * @return boolean value whether the Directory was succesfully written to
     * Disk
     */
    bool Flush();

    /**
     * Deletes the DirectoryEntry associated with this fileName in RAM. Does
     * not modify disk.
     * @param fileName File name of DirectoryEntry to be deleted
     * @return True if successfully deleted, False if unable to delete or
     * fileName was not found
     */
    bool Delete(char* fileName);

    /**
     * Adds a new directory entry to Directory BlockGroup in RAM. Does not
     * modify disk.
     * @param fileName file name for the new entry
     * @param FCB File Control Block for the new Entry
     * @return True if adding entry was successful
     */
    bool Add(char* fileName, int FCB);

    /**
     * Renames the file name of a Directory Entry in RAM associated with param
     * fileName. Does not modify Disk.
     * @param fileName old file name
     * @param newName new file Name
     * @return True if rename was successful
     */
    bool Rename(char* fileName, char* newName);

    /**
     * Deletes all the directory entries from Directory BlockGroup in RAM. Does
     * not modify Disk.
     * @return True if clear operation was successful
     */
    bool Clear();

    /**
     * Deletes itself from the disk. Returns the blocks to freelist. Sets
     * directoryEntries empty.
     * @return True if delete was successful
     */
    bool DeleteDirectory();

    /**
     * Writes the directory values to disk: start block number, end block
     * number, number of blocks and number of directory entries into the
     * master block. Modifies the disk.
     * @return returns whether write was successful.
     */
    bool writeDirToMaster();
    
    static void Test();

    /**
     * The number of maximum entries stored in a block
     */
    static const int DIRECTORY_ENTRIES_PER_BLOCK = 21;

protected:

    vector<DirectoryEntry> m_directoryEntries;

private:
    /**
     * The total number of directory entries
     */

    int m_numDirEntries;

    BlockGroup * m_bg;
    FreeList * m_freelist;
};

#endif	/* DIRECTORY_H */

